<?php
/**
 * Created by PhpStorm.
 * User: User
 * Date: 2017/12/14
 * Time: 10:27
 */

namespace Kinfy\View\Engine;
class Blade
{
    //模板根目录
    protected $base_dir = '';
    //模板子模板数组
    protected $sub_tpls = [];
    //模板标签
    protected $tag = ['{', '}'];
    //要处理的模板字符串
    public $template = '';
    //layout模板标签对应的数据
    private $tag_body = [];

    public function getSubTpls()
    {
        return $this->sub_tpls;
    }

    public function setBaseDir($dir)
    {
        $this->base_dir = $dir;
    }

    private function _replace($find, $replace)
    {
        $pattern = "/{$this->tag[0]}\s*{$find}\s*{$this->tag[1]}/is";
        $this->template = preg_replace(
            $pattern,
            $replace,
            $this->template
        );
    }

    //变量
    public function varExp()
    {
        $exp = '(\$[a-zA-Z_][0-9a-zA-Z_\'\"\[\]]*)';
        $replace = "<?php if(isset(\\1)){echo \\1;}?>";
        $this->_replace($exp, $replace);
    }

    //if
    public function ifExp()
    {
        $exp = 'if\s+(.*?)';
        $replace = "<?php if(\\1){ ?>";
        $this->_replace($exp, $replace);
    }

    //else
    public function elseExp()
    {
        $exp = 'else';
        $replace = "<?php }else{ ?>";
        $this->_replace($exp, $replace);
    }

    //elseif
    public function elseifExp()
    {
        $exp = 'else\s*if\s+(.*?)';
        $replace = "<?php }elseif(\\1){ ?>";
        $this->_replace($exp, $replace);
    }

    //endif {/if}
    public function endifExp()
    {
        $exp = '\/if';
        $replace = "<?php } ?>";
        $this->_replace($exp, $replace);
    }

    //loop
    public function loopExp()
    {
        $exp = '(([a-zA-Z]+)\s*:\s*)?loop\s+(.*?)\s+in\s+(.*?)';
        $replace = "<?php 
        if(is_array(\\4)){
            \$\\2_COUNT = count(\\4);
        }
        \$\\2_INDEX = 0;
        foreach(\\4 as \\3){ 
            \$\\2_INDEX++;
        ?>";
        $this->_replace($exp, $replace);
    }

    //loop
    public function endloopExp()
    {
        $exp = '\/loop';
        $replace = "<?php } ?>";
        $this->_replace($exp, $replace);
    }


    //extends
    public function extendsExp()
    {
        $exp = 'extends\s+(.*?)';
        $pattern = "/{$this->tag[0]}\s*{$exp}\s*{$this->tag[1]}/is";
        $ismatch = preg_match($pattern, $this->template, $matches);
        if ($ismatch) {
            $master = $this->readTpl($matches[1]);
            $this->getTagBody($master);
            $exp_ext = '@(.*?)';
            $pattern_ext = "/{$this->tag[0]}\s*{$exp_ext}\s*{$this->tag[1]}/is";
            $master = preg_replace_callback($pattern_ext, [$this, 'replaceTag'], $master);
            $this->template = $master;
        }
    }

    private function replaceTag($matches)
    {
        $tag = $matches[1];
        return isset($this->tag_body[$tag]) ? $this->tag_body[$tag] :'';
    }

    private function getTagBody($master)
    {
        $exp_ext = '@(.*?)';
        $pattern_ext = "/{$this->tag[0]}\s*{$exp_ext}\s*{$this->tag[1]}/is";
        preg_match_all($pattern_ext, $master, $matches_ext);
        $this->tag_body = [];
        foreach ($matches_ext[1] as $ext) {
            $pattern_body = "/{$this->tag[0]}\s*({$ext})\s*{$this->tag[1]}(.*?){$this->tag[0]}\s*\/{$ext}\s*{$this->tag[1]}/is";
            $ismatched = preg_match($pattern_body, $this->template, $matches_body);
            if( $ismatched){
                $this->tag_body[$matches_body[1]] = $matches_body[2];
            }
        }
    }

    //include
    public function includeExp()
    {
        $exp = 'include\s+(.*?)';
        $pattern = "/{$this->tag[0]}\s*{$exp}\s*{$this->tag[1]}/is";
        $this->template = preg_replace_callback(
            $pattern,
            [$this, 'includeTpl'],
            $this->template
        );
    }

    private function includeTpl($matches)
    {
        return $this->readTpl($matches[1]);
    }

    private function readTpl($tpl)
    {
        //检查模板是否死循环调用
        if (in_array($tpl, $this->sub_tpls)) {
            die("{$tpl} 文件调用产生死循环!");
        } else {
            $this->sub_tpls[] = $tpl;
        }

        $file = "{$this->base_dir}/{$tpl}.tpl.php";

        if (!file_exists($file)) {
            die("{$file}文件不存在，或者不可读取！");
        }
        $content = file_get_contents($file);

        $exp = 'include\s+(.*?)';
        $pattern = "/{$this->tag[0]}\s*{$exp}\s*{$this->tag[1]}/is";
        $content = preg_replace_callback(
            $pattern,
            [$this, 'includeTpl'],
            $content
        );

        return $content;
    }

    public function addSubTpl($tpl)
    {
        $this->sub_tpls[] = $tpl;
    }


}